<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>更新时的一个问题</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<!-- 准备好一个容器-->
	<div id="root">
		<h2>人员列表</h2>
		<button @click="updateMei">更新马冬梅的信息</button>
		<ul>
			<li v-for="(p,index) of persons" :key="p.id">
				{{p.name}}-{{p.age}}-{{p.sex}}
			</li>
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		const vm = new Vue({
			el: '#root',
			data: {
				persons: [
					{ id: '001', name: '马冬梅', age: 30, sex: '女' },
					{ id: '002', name: '周冬雨', age: 31, sex: '女' },
					{ id: '003', name: '周杰伦', age: 18, sex: '男' },
					{ id: '004', name: '温兆伦', age: 19, sex: '男' }
				]
			},
			methods: {
				//在 Vue 实例中，`data` 属性是用户定义的用于存储数据的对象，而 `_data` 是 Vue 内部用于存储数据的对象。它们之间的关系是 Vue 实例的 `data` 属性实际上是对 `_data` 的代理。
				updateMei() {
					// this.persons[0].name = '马老师' //奏效
					// this.persons[0].age = 50 //奏效
					// this.persons[0].sex = '男' //奏效    注意vm是vue实例vm._data.student =vm.student ，原理就时前面讲的vue的数据代理，把vm中的属性代理到了_data
					// this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'}  																		    
					this.persons.splice(0, 1, { id: '001', name: '马老师', age: 50, sex: '男' })
				}
			}
		})
		//上面案例直接修改数组的第一个元素会失效，原因是Vue把data封装为_data时做了响应式处理(代理)，给所有的属性都加了get和set,类似于Object.defineProperty，
		// 但是这里的直接通过索引整个赋值并不会做响应式处理（不会把data数据代理到_data），也就导致并不会实际修改_data，也就是vue的实际数据，除非使用Vue.set做响应式设值。
		// Vue在实现响应式数据时，会使用一些特殊的技巧来监听对象的属性变化，但这些技巧对数组的处理比较复杂。Vue能够检测到通过索引直接修改数组元素的情况，因为Vue会拦截数组
		//的变异方法（例如 push、pop、shift、unshift、splice 和 sort），从而能够在这些方法执行时触发视图更新。
		// 然而，直接通过索引赋值的方式修改数组元素this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'}，绕过了 Vue 的代理，Vue 无法检测到这样的变化，
		//因此不会触发视图更新。this.persons[0].name = '马老师' 这种方式可以生效的原因是因为name是vue实例的一个属性，可以触发响应式代理的更新.

	</script>

</html>